﻿using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;

namespace Scheduler
{
    public class WorkerTaskScheduler : TaskScheduler, IDisposable
    {
        private readonly BlockingCollection<Task> m_queue = new BlockingCollection<Task>();

        private Thread _runThread;

        public WorkerTaskScheduler()
        {
            _runThread = new Thread(Run);
            _runThread.IsBackground = true;//设为为后台线程，当主线程结束时线程自动结束
            _runThread.Start();
            _runThread.Priority = ThreadPriority.Highest;
        }

        private void Run()
        {
            //Console.WriteLine($"SpecTaskScheduler, ThreadID: {Thread.CurrentThread.ManagedThreadId}");
            Task t;
            while (m_queue.TryTake(out t, Timeout.Infinite))
            {
                TryExecuteTask(t);//在当前线程执行Task
            }
        }

        protected override IEnumerable<Task> GetScheduledTasks()
        {
            return m_queue;
        }

        protected override void QueueTask(Task task)
        {
            m_queue.Add(task);//t.Start(MyTaskScheduler.Current)时，将Task加入到队列中
        }

        //当执行该函数时，程序正在尝试以同步的方式执行Task代码
        protected override bool TryExecuteTaskInline(Task task, bool taskWasPreviouslyQueued)
        {
            return false;
        }

        public void Dispose()
        {
            _runThread.Abort();
        }
    }
}